/********************************************************************************
 *    Copyright (C) 2014 GSI Helmholtzzentrum fuer Schwerionenforschung GmbH    *
 *                                                                              *
 *              This software is distributed under the terms of the             *
 *              GNU Lesser General Public Licence (LGPL) version 3,             *
 *                  copied verbatim in the file "LICENSE"                       *
 ********************************************************************************/
#include "HiMusicMappingTask.h"
#include "FairRootManager.h"
#include "HiMusicUnpackedData.h"
#include "HiMusicMappedData.h"
#include <yaml-cpp/yaml.h>
#include <fstream>
#include <sstream>
#include <array>
#include <vector>

HiMusicMappingTask::HiMusicMappingTask() : FairTask("HiMusicMappingTask") {}

HiMusicMappingTask::~HiMusicMappingTask() {}

InitStatus HiMusicMappingTask::Init()
{
    FairRootManager *ioman = FairRootManager::Instance();
    if (!ioman)
        return kFATAL;

    fUnpackedDataArray = (TClonesArray *)ioman->GetObject("HiMusicUnpackedData");
    if (!fUnpackedDataArray)
        return kFATAL;

    fMappedArray = new TClonesArray("HiMusicMappedData");
    ioman->Register("HiMusicMappedData", "Mapping", fMappedArray, kTRUE);

    LoadMappingFromYAML();

    return kSUCCESS;
}
InitStatus HiMusicMappingTask::ReInit()
{
    LOG(info) << "Initilization of NewTask";
    return kSUCCESS;
}

void HiMusicMappingTask::LoadMappingFromYAML()
{
    fMapTable.clear();
    YAML::Node config = YAML::LoadFile(fMapYamlFile.Data());

    for (auto pxiNode : config)
    {
        std::string pxiKey = pxiNode.first.as<std::string>(); // e.g. "PXI_12"
        uint8_t pxi = std::stoi(pxiKey.substr(4));

        for (auto feeNode : pxiNode.second)
        {
            std::string feeKey = feeNode.first.as<std::string>(); // e.g. "FEE_0"
            uint8_t fee = std::stoi(feeKey.substr(4));

            std::string detName = feeNode.second["DetectorName"].as<std::string>();
            uint8_t detID = feeNode.second["DetectorID"].as<uint8_t>();
            fMapTable[{pxi, fee}] = {TString(detName.c_str()), detID};
        }
    }

    LOG(info) << "Loaded " << fMapTable.size() << " mapping entries from " << fMapYamlFile;
}

void HiMusicMappingTask::Exec(Option_t *)
{
    LOG(debug) << "Exec of HiMusicMappingTask"; 
    fMappedArray->Clear();

    auto *UnpackedData = (HiMusicUnpackedData *)fUnpackedDataArray->At(0);
    auto key = std::make_pair(UnpackedData->GetPxiID(), UnpackedData->GetFeeID());

    auto it = fMapTable.find(key);
    if (it == fMapTable.end())
        return; // 未定义映射则跳过

    auto [detName, detID] = it->second;

    auto *mapped = new ((*fMappedArray)[0]) HiMusicMappedData();
    mapped->SetDetID(detID);
    mapped->SetTimeSliceID(UnpackedData->GetTimeSliceID());
    auto &data = UnpackedData->GetWaveformData();
    for (size_t ch = 0; ch < data.size(); ++ch)
    {
        HiMusicWaveForm wf;
        wf.SetNPoints(data[ch].size());
        wf.SetTStep(25); // 假设采样间隔为25ns
        if (ch < 8)
            wf.SetType(0); // 前8为阳极信号
        else
            wf.SetType(1); // 最后为阴极信号
        std::vector<uint16_t> vec1(data[ch].begin(), data[ch].end());
        wf.SetData(vec1);

        mapped->AddChannel(wf);
    }
}

void HiMusicMappingTask::SetParContainers()
{
    // LOG(info) << "SetParContainers of NewTask";
}

void HiMusicMappingTask::Finish() {}
